#pragma once

namespace yzrilyzr_soundbank{
	EBCLASS(DLSModulator){
	 // DLS1 Destinations
	public:
	static constexpr int const CONN_DST_NONE=0x000; // 0
	static constexpr int const CONN_DST_GAIN=0x001; // cB
	static constexpr int const CONN_DST_RESERVED=0x002;
	static constexpr int const CONN_DST_PITCH=0x003; // cent
	static constexpr int const CONN_DST_PAN=0x004; // 0.1%
	static constexpr int const CONN_DST_LFO_FREQUENCY=0x104; // cent (default 5 Hz)
	static constexpr int const CONN_DST_LFO_STARTDELAY=0x105; // timecent
	static constexpr int const CONN_DST_EG1_ATTACKTIME=0x206; // timecent
	static constexpr int const CONN_DST_EG1_DECAYTIME=0x207; // timecent
	static constexpr int const CONN_DST_EG1_RESERVED=0x208; 
	static constexpr int const CONN_DST_EG1_RELEASETIME=0x209; // timecent
	static constexpr int const CONN_DST_EG1_SUSTAINLEVEL=0x20A; // 0.1%
	static constexpr int const CONN_DST_EG2_ATTACKTIME=0x30A; // timecent
	static constexpr int const CONN_DST_EG2_DECAYTIME=0x30B; // timecent
	static constexpr int const CONN_DST_EG2_RELEASETIME=0x30D; // timecent
	static constexpr int const CONN_DST_EG2_RESERVED=0x30C; 
	static constexpr int const CONN_DST_EG2_SUSTAINLEVEL=0x30E; // 0.1%
	// DLS2 Destinations
	static constexpr int const CONN_DST_KEYNUMBER=0x005;
	static constexpr int const CONN_DST_LEFT=0x010; // 0.1%
	static constexpr int const CONN_DST_RIGHT=0x011; // 0.1%
	static constexpr int const CONN_DST_CENTER=0x012; // 0.1%
	static constexpr int const CONN_DST_LEFTREAR=0x013; // 0.1%
	static constexpr int const CONN_DST_RIGHTREAR=0x014; // 0.1%
	static constexpr int const CONN_DST_LFE_CHANNEL=0x015; // 0.1%
	static constexpr int const CONN_DST_CHORUS=0x080; // 0.1%
	static constexpr int const CONN_DST_REVERB=0x081; // 0.1%
	static constexpr int const CONN_DST_VIB_FREQUENCY=0x114; // cent
	static constexpr int const CONN_DST_VIB_STARTDELAY=0x115; // dB
	static constexpr int const CONN_DST_EG1_DELAYTIME=0x20B; // timecent
	static constexpr int const CONN_DST_EG1_HOLDTIME=0x20C; // timecent
	static constexpr int const CONN_DST_EG1_SHUTDOWNTIME=0x20D; // timecent
	static constexpr int const CONN_DST_EG2_DELAYTIME=0x30F; // timecent
	static constexpr int const CONN_DST_EG2_HOLDTIME=0x310; // timecent
	static constexpr int const CONN_DST_FILTER_CUTOFF=0x500; // cent
	static constexpr int const CONN_DST_FILTER_Q=0x501; // dB

	// DLS1 Sources
	static constexpr int const CONN_SRC_NONE=0x000; // 1
	static constexpr int const CONN_SRC_LFO=0x001; // linear (sine wave)
	static constexpr int const CONN_SRC_KEYONVELOCITY=0x002; // ??db or velocity??
	static constexpr int const CONN_SRC_KEYNUMBER=0x003; // ??cent or keynumber??
	static constexpr int const CONN_SRC_EG1=0x004; // linear direct from eg
	static constexpr int const CONN_SRC_EG2=0x005; // linear direct from eg
	static constexpr int const CONN_SRC_PITCHWHEEL=0x006; // linear -1..1
	static constexpr int const CONN_SRC_CC1=0x081; // linear 0..1
	static constexpr int const CONN_SRC_CC7=0x087; // linear 0..1
	static constexpr int const CONN_SRC_CC10=0x08A; // linear 0..1
	static constexpr int const CONN_SRC_CC11=0x08B; // linear 0..1
	static constexpr int const CONN_SRC_RPN0=0x100; // ?? // Pitch Bend Range
	static constexpr int const CONN_SRC_RPN1=0x101; // ?? // Fine Tune
	static constexpr int const CONN_SRC_RPN2=0x102; // ?? // Course Tune
	// DLS2 Sources
	static constexpr int const CONN_SRC_POLYPRESSURE=0x007; // linear 0..1
	static constexpr int const CONN_SRC_CHANNELPRESSURE=0x008; // linear 0..1
	static constexpr int const CONN_SRC_VIBRATO=0x009; // linear 0..1
	static constexpr int const CONN_SRC_MONOPRESSURE=0x00A; // linear 0..1
	static constexpr int const CONN_SRC_CC91=0x0DB; // linear 0..1
	static constexpr int const CONN_SRC_CC93=0x0DD; // linear 0..1
	// DLS1 Transforms
	static constexpr int const CONN_TRN_NONE=0x000;
	static constexpr int const CONN_TRN_CONCAVE=0x001;
	// DLS2 Transforms
	static constexpr int const CONN_TRN_CONVEX=0x002;
	static constexpr int const CONN_TRN_SWITCH=0x003;
	static constexpr int const DST_FORMAT_CB=1;
	static constexpr int const DST_FORMAT_CENT=1;
	static constexpr int const DST_FORMAT_TIMECENT=2;
	static constexpr int const DST_FORMAT_PERCENT=3;
	uint16_t source;
	uint16_t control;
	uint16_t destination;
	uint16_t transform;
	int32_t scale;
	int32_t version=1;

	public:
	int32_t getControl(){
		return control;
	}

	void setControl(int32_t control){
		this->control=control;
	}

	static int32_t getDestinationFormat(int32_t destination){
		if(destination == CONN_DST_GAIN)
			return DST_FORMAT_CB;
		if(destination == CONN_DST_PITCH)
			return DST_FORMAT_CENT;
		if(destination == CONN_DST_PAN)
			return DST_FORMAT_PERCENT;

		if(destination == CONN_DST_LFO_FREQUENCY)
			return DST_FORMAT_CENT;
		if(destination == CONN_DST_LFO_STARTDELAY)
			return DST_FORMAT_TIMECENT;

		if(destination == CONN_DST_EG1_ATTACKTIME)
			return DST_FORMAT_TIMECENT;
		if(destination == CONN_DST_EG1_DECAYTIME)
			return DST_FORMAT_TIMECENT;
		if(destination == CONN_DST_EG1_RELEASETIME)
			return DST_FORMAT_TIMECENT;
		if(destination == CONN_DST_EG1_SUSTAINLEVEL)
			return DST_FORMAT_PERCENT;

		if(destination == CONN_DST_EG2_ATTACKTIME)
			return DST_FORMAT_TIMECENT;
		if(destination == CONN_DST_EG2_DECAYTIME)
			return DST_FORMAT_TIMECENT;
		if(destination == CONN_DST_EG2_RELEASETIME)
			return DST_FORMAT_TIMECENT;
		if(destination == CONN_DST_EG2_SUSTAINLEVEL)
			return DST_FORMAT_PERCENT;

		if(destination == CONN_DST_KEYNUMBER)
			return DST_FORMAT_CENT; // NOT SURE WITHOUT DLS 2 SPEC
		if(destination == CONN_DST_LEFT)
			return DST_FORMAT_CB;
		if(destination == CONN_DST_RIGHT)
			return DST_FORMAT_CB;
		if(destination == CONN_DST_CENTER)
			return DST_FORMAT_CB;
		if(destination == CONN_DST_LEFTREAR)
			return DST_FORMAT_CB;
		if(destination == CONN_DST_RIGHTREAR)
			return DST_FORMAT_CB;
		if(destination == CONN_DST_LFE_CHANNEL)
			return DST_FORMAT_CB;
		if(destination == CONN_DST_CHORUS)
			return DST_FORMAT_PERCENT;
		if(destination == CONN_DST_REVERB)
			return DST_FORMAT_PERCENT;

		if(destination == CONN_DST_VIB_FREQUENCY)
			return DST_FORMAT_CENT;
		if(destination == CONN_DST_VIB_STARTDELAY)
			return DST_FORMAT_TIMECENT;

		if(destination == CONN_DST_EG1_DELAYTIME)
			return DST_FORMAT_TIMECENT;
		if(destination == CONN_DST_EG1_HOLDTIME)
			return DST_FORMAT_TIMECENT;
		if(destination == CONN_DST_EG1_SHUTDOWNTIME)
			return DST_FORMAT_TIMECENT;

		if(destination == CONN_DST_EG2_DELAYTIME)
			return DST_FORMAT_TIMECENT;
		if(destination == CONN_DST_EG2_HOLDTIME)
			return DST_FORMAT_TIMECENT;

		if(destination == CONN_DST_FILTER_CUTOFF)
			return DST_FORMAT_CENT;
		if(destination == CONN_DST_FILTER_Q)
			return DST_FORMAT_CB;

		return -1;
	}

	static yzrilyzr_lang::String getDestinationName(int32_t destination){
		if(destination == CONN_DST_GAIN)
			return "gain";
		if(destination == CONN_DST_PITCH)
			return "pitch";
		if(destination == CONN_DST_PAN)
			return "pan";

		if(destination == CONN_DST_LFO_FREQUENCY)
			return "lfo1.freq";
		if(destination == CONN_DST_LFO_STARTDELAY)
			return "lfo1.delay";

		if(destination == CONN_DST_EG1_ATTACKTIME)
			return "eg1.attack";
		if(destination == CONN_DST_EG1_DECAYTIME)
			return "eg1.decay";
		if(destination == CONN_DST_EG1_RELEASETIME)
			return "eg1.release";
		if(destination == CONN_DST_EG1_SUSTAINLEVEL)
			return "eg1.sustain";

		if(destination == CONN_DST_EG2_ATTACKTIME)
			return "eg2.attack";
		if(destination == CONN_DST_EG2_DECAYTIME)
			return "eg2.decay";
		if(destination == CONN_DST_EG2_RELEASETIME)
			return "eg2.release";
		if(destination == CONN_DST_EG2_SUSTAINLEVEL)
			return "eg2.sustain";

		if(destination == CONN_DST_KEYNUMBER)
			return "keynumber";
		if(destination == CONN_DST_LEFT)
			return "left";
		if(destination == CONN_DST_RIGHT)
			return "right";
		if(destination == CONN_DST_CENTER)
			return "center";
		if(destination == CONN_DST_LEFTREAR)
			return "leftrear";
		if(destination == CONN_DST_RIGHTREAR)
			return "rightrear";
		if(destination == CONN_DST_LFE_CHANNEL)
			return "lfe_channel";
		if(destination == CONN_DST_CHORUS)
			return "chorus";
		if(destination == CONN_DST_REVERB)
			return "reverb";

		if(destination == CONN_DST_VIB_FREQUENCY)
			return "vib.freq";
		if(destination == CONN_DST_VIB_STARTDELAY)
			return "vib.delay";

		if(destination == CONN_DST_EG1_DELAYTIME)
			return "eg1.delay";
		if(destination == CONN_DST_EG1_HOLDTIME)
			return "eg1.hold";
		if(destination == CONN_DST_EG1_SHUTDOWNTIME)
			return "eg1.shutdown";

		if(destination == CONN_DST_EG2_DELAYTIME)
			return "eg2.delay";
		if(destination == CONN_DST_EG2_HOLDTIME)
			return "eg.2hold";

		if(destination == CONN_DST_FILTER_CUTOFF)
			return "filter.cutoff"; // NOT SURE WITHOUT DLS 2 SPEC
		if(destination == CONN_DST_FILTER_Q)
			return "filter.q"; // NOT SURE WITHOUT DLS 2 SPEC

		return "";
	}

	static yzrilyzr_lang::String getSourceName(int32_t source){
		if(source == CONN_SRC_NONE)
			return "none";
		if(source == CONN_SRC_LFO)
			return "lfo";
		if(source == CONN_SRC_KEYONVELOCITY)
			return "keyonvelocity";
		if(source == CONN_SRC_KEYNUMBER)
			return "keynumber";
		if(source == CONN_SRC_EG1)
			return "eg1";
		if(source == CONN_SRC_EG2)
			return "eg2";
		if(source == CONN_SRC_PITCHWHEEL)
			return "pitchweel";
		if(source == CONN_SRC_CC1)
			return "cc1";
		if(source == CONN_SRC_CC7)
			return "cc7";
		if(source == CONN_SRC_CC10)
			return "c10";
		if(source == CONN_SRC_CC11)
			return "cc11";

		if(source == CONN_SRC_POLYPRESSURE)
			return "polypressure";
		if(source == CONN_SRC_CHANNELPRESSURE)
			return "channelpressure";
		if(source == CONN_SRC_VIBRATO)
			return "vibrato";
		if(source == CONN_SRC_MONOPRESSURE)
			return "monopressure";
		if(source == CONN_SRC_CC91)
			return "cc91";
		if(source == CONN_SRC_CC93)
			return "cc93";
		return "";
	}

	int32_t getDestination(){
		return destination;
	}

	void setDestination(int32_t destination){
		this->destination=destination;
	}

	int32_t getScale(){
		return scale;
	}

	void setScale(int32_t scale){
		this->scale=scale;
	}

	int32_t getSource(){
		return source;
	}

	void setSource(int32_t source){
		this->source=source;
	}

	int32_t getVersion(){
		return version;
	}

	void setVersion(int32_t version){
		this->version=version;
	}

	int32_t getTransform(){
		return transform;
	}

	void setTransform(int32_t transform){
		this->transform=transform;
	}
	};
}